﻿using System;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace TCPServerTest
{

    class Program
    {
        static Thread threadWatch = null;
        static Socket socketWatch = null;
        //创建一个负责和客户端通信的套接字 
        static List<Socket> socConnections = new List<Socket>();
        static List<Thread> ClientRecThread = new List<Thread>();
        static void Main(string[] args)
        {
            string ipstr;
            int portint;
            Console.WriteLine("请输入IP地址：");
            ipstr = Console.ReadLine();
            Console.WriteLine("请输入端口号：");
            portint = Console.Read();
            Console.WriteLine("IP:Port—{0}:{1}", ipstr, portint);


            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //服务端发送信息 需要1个IP地址和端口号
            IPAddress ipaddress = IPAddress.Parse(ipstr); //获取文本框输入的IP地址
            //将IP地址和端口号绑定到网络节点endpoint上
            IPEndPoint endpoint = new IPEndPoint(ipaddress, portint); //获取文本框上输入的端口号
            //监听绑定的网络节点
            socketWatch.Bind(endpoint);
            //将套接字的监听队列长度限制为20
            socketWatch.Listen(20);
            //创建一个监听线程
            threadWatch = new Thread(WatchConnecting);
            //将窗体线程设置为与后台同步
            threadWatch.IsBackground = true;
            //启动线程
            threadWatch.Start();
            //启动线程后 txtMsg文本框显示相应提示
            Console.WriteLine("开始监听客户端传来的信息!" + "\r\n");
            while (true) ;
        }

        private static void WatchConnecting(object obj)
        {
            while (true)  //持续不断监听客户端发来的请求
            {
                Socket socConnection = socketWatch.Accept();
                IPEndPoint clientipe = (IPEndPoint)socConnection.RemoteEndPoint;
                string ipport = clientipe.Address.ToString();
                string portint = clientipe.Port.ToString();
                Console.WriteLine("客户端连接成功—{0}:{1}" + "\r\n", ipport, portint);
                //创建一个通信线程
                Thread thr = new Thread(RecvMessage);
                thr.IsBackground = true;
                socConnections.Add(socConnection);
                //启动线程
                thr.Start(socConnection);
                ClientRecThread.Add(thr);
            }
        }

        /// <summary>
        /// 接受客户端的消息
        /// </summary>
        /// <param name="clientsocket"></param>
        private static void RecvMessage(object client_socket)
        {
            Socket inSocket = client_socket as Socket;
            IPEndPoint clientipe1 = (IPEndPoint)inSocket.RemoteEndPoint;
            string ipstr = clientipe1.Address.ToString();
            string portstr = clientipe1.Port.ToString();
            byte[] strbyte = new byte[1024];
            int count = -1;
            while (inSocket.Receive(strbyte)>0)
            {
                try
                {
                    String restr = "";
                    for (int i = 0; i < strbyte.Length; i++)
                    {
                        if (strbyte[i] == '\0') break;
                        restr+= strbyte[i];
                    }
                    string ret = Encoding.UTF8.GetString(strbyte);
                    Console.WriteLine(restr);
                    Console.WriteLine("{0}给你发送了消息：{1}", inSocket.RemoteEndPoint, ret);
                    String sstr_temp = "谢谢你，收到啦！";
                    SendMessage(inSocket, sstr_temp);
                }
                catch (Exception)
                {
                    //客户端离去时终止线程
                    Console.WriteLine("{0}:{1}的客户端已经离去！", clientipe1.Address.ToString(), ipstr, portstr);
                }
                Array.Clear(strbyte,0, strbyte.Length);
            }
        }

        /// <summary>
        /// 向客户端返回消息
        /// </summary>
        private static void SendMessage(object client_socket, String sendstr)
        {
            Socket inSocket = client_socket as Socket;
            IPEndPoint clientipe1 = (IPEndPoint)inSocket.RemoteEndPoint;
            string ipstr = clientipe1.Address.ToString();
            string portstr = clientipe1.Port.ToString();
            try
            {
                //Console.WriteLine("请输入要发送的消息：");
                //string str = Console.ReadLine();
                byte[] strbyte = Encoding.UTF8.GetBytes(sendstr);
                inSocket.Send(strbyte);
            }
            catch (Exception)
            {
                //客户端离去时终止线程
                Console.WriteLine("{0}:{1}的客户端已经离去！", clientipe1.Address.ToString(), ipstr, portstr);
            }
        }
    }
}
